package org.onion.pattern.event.publish;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Getter
@Setter
@Slf4j
public class DefaultEventChannelPublisher implements EventChannelPublisher, ApplicationContextAware {

    private final Map<String, EventPublishChannel> channels = new ConcurrentHashMap<>();
    private       ApplicationContext               applicationContext;

    @Override
    public synchronized void register(EventPublishChannel channel) {
        if (this.channels.containsKey(channel.getClass().getName())) {
            return;
        }
        this.channels.put(channel.getClass().getName(), channel);
    }

    @Override
    public void publish(Object msg) {
        log.debug("【事件通道】 发送 {}", msg);

        //从注册中获取
        for (Map.Entry<String, EventPublishChannel> entry : channels.entrySet()) {
            EventPublishChannel channel = entry.getValue();
            if (!channel.support(msg)) {
                continue;
            }
            channel.send(msg);
            return;
        }

        //从spring 容器中取
        Map<String, EventPublishChannel> beansOfType = applicationContext.getBeansOfType(EventPublishChannel.class);
        if (!beansOfType.isEmpty()) {
            for (EventPublishChannel channel : beansOfType.values()) {
                if (this.channels.containsKey(msg.getClass().getName())) {
                    continue;
                }
                this.channels.put(msg.getClass().getName(), channel);

                if (channel.support(msg)) {
                    channel.send(msg);
                    return;
                }
            }
        }

        log.error("【事件通道】 没有匹配到通道 {}", msg);
    }

//    @Override
//    public void publish(List<Object> msgList) {
//        for (Object msg : msgList) {
//            this.publish(msg);
//        }
//    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}
